﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using THSLib;
using THSERP.BaseProvider;
using THSERP.BusinessEntities;
namespace THSERP.Modules.CustomerPayment
{
    public class CustomerPaymentModule : BaseModuleERP
    {
        #region Utility functions
        public static AROpenDocumentsInfo GenerateOpenDocumentFromInvoice(ARInvoicesInfo objInvoicesInfo)
        {
            THSDbUtil dbUtil = new THSDbUtil();
            AROpenDocumentsInfo objOpenDocumentsInfo = new AROpenDocumentsInfo();
            THSUtil.CopyMainObjects(objInvoicesInfo, objOpenDocumentsInfo);

            //Set own properties of open document
            objOpenDocumentsInfo.AACreatedUser = THSApp.CurrentUser;
            objOpenDocumentsInfo.AACreatedDate = DateTime.Now;
            objOpenDocumentsInfo.AROpenDocumentNo = objInvoicesInfo.ARInvoiceReference;
            objOpenDocumentsInfo.FK_ARInvoiceID = objInvoicesInfo.ARInvoiceID;
            objOpenDocumentsInfo.AROpenDocumentType = objInvoicesInfo.ARInvoiceTypeCombo;
            return objOpenDocumentsInfo;
        }

        public static bool AcceptPayment(THSList<ARDocumentPaymentDetailsInfo> lstPayments, int customerID, double totalAmount, ref double receivingAmount)
        {
            receivingAmount = 0;
            foreach (ARDocumentPaymentDetailsInfo objDocumentPaymentDetailsInfo in lstPayments)
            {
                if (objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount > 0)
                {
                    switch (objDocumentPaymentDetailsInfo.ARPaymentMethodCombo)
                    {
                        case ADConfigValueUtility.cstPaymentMethodAccount:
                            {
                                ARCustomersController objCustomersController = new ARCustomersController();
                                ARCustomersInfo objCustomersInfo = (ARCustomersInfo)objCustomersController.GetObjectByID(customerID);
                                if (objCustomersInfo.ARCustomerCreditLimit - objCustomersInfo.ARCustomerOwing < objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount)
                                {
                                    MessageBox.Show("The account payment exceeds the available limit of this customer. Please define credit limit or payment amount again", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                    return false;
                                }
                            }
                            break;
                        case ADConfigValueUtility.cstPaymentMethodCreditNote:
                            {
                                ARCreditNotesController objCreditNotesController = new ARCreditNotesController();
                                ARCreditNotesInfo objCreditNotesInfo = (ARCreditNotesInfo)objCreditNotesController.GetCreditNoteByNoAndType(objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailInfo.Trim(), Modules.CreditNote.CreditNoteModule.cstCreditNoteTypeCreditNote);
                                if (objCreditNotesInfo == null)
                                {
                                    MessageBox.Show("The credit note number does not exist", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    return false;
                                }
                                if (objCreditNotesInfo.ARCreditNoteValidateDate.CompareTo(DateTime.Now) < 0)
                                {
                                    MessageBox.Show("The credit note has expired.", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    return false;
                                }
                                if (objCreditNotesInfo.ARCreditNoteRemainingAmount < objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount)
                                {
                                    MessageBox.Show("The credit note payment exceeds its remaining amount. Please define payment amount again", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                    return false;
                                }
                                objDocumentPaymentDetailsInfo.FK_ARCreditNoteID = objCreditNotesInfo.ARCreditNoteID;
                            }
                            break;
                        case ADConfigValueUtility.cstPaymentMethodGiftVoucher:
                            {
                                ARCreditNotesController objCreditNotesController = new ARCreditNotesController();
                                ARCreditNotesInfo objCreditNotesInfo = (ARCreditNotesInfo)objCreditNotesController.GetCreditNoteByNoAndType(objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailInfo.Trim(), Modules.CreditNote.CreditNoteModule.cstCreditNoteTypeGiftVoucher);
                                if (objCreditNotesInfo == null)
                                {
                                    MessageBox.Show("The gift voucher number does not exist", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    return false;
                                }
                                if (objCreditNotesInfo.ARCreditNoteValidateDate.CompareTo(DateTime.Now) < 0)
                                {
                                    MessageBox.Show("The gift voucher has expired.", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    return false;
                                }
                                if (objCreditNotesInfo.ARCreditNoteRemainingAmount < objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount)
                                {
                                    MessageBox.Show("The gift voucher payment exceeds its remaining amount. Please define payment amount again", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                    return false;
                                }
                                objDocumentPaymentDetailsInfo.FK_ARCreditNoteID = objCreditNotesInfo.ARCreditNoteID;
                            }
                            break;
                    }
                    receivingAmount += objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                }
            }
            if (receivingAmount < totalAmount)
            {
                MessageBox.Show("Số tiền thanh toán không được nhỏ hơn số tiền của bill.Vui lòng xem lại.", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        }

        public static bool AcceptRefund(THSList<ARDocumentPaymentDetailsInfo> lstPayments, double totalRefund, ref double refundAmount)
        {
            refundAmount = 0;
            foreach (ARDocumentPaymentDetailsInfo objDocumentPaymentDetailsInfo in lstPayments)
                refundAmount += objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
            if (refundAmount < totalRefund)
            {
                MessageBox.Show("The refund amount is less than the total refund. Please define refund amount again.", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        }

        public static void TakePayment(AROpenDocumentsInfo objOpenDocumentsInfo, double totalAmount, THSList<ARDocumentPaymentDetailsInfo> lstPaymentDetails)
        {
            if (objOpenDocumentsInfo.AROpenDocumentID > 0)
            {
                //Calculate receiving amount from customer
                double receivingAmount = 0;
                foreach (ARDocumentPaymentDetailsInfo objDocumentPaymentDetailsInfo in lstPaymentDetails)
                {
                    if (objOpenDocumentsInfo.AROpenDocumentType == ADConfigValueUtility.cstOpenDocumentTypeGoodsRefund)
                        objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount = -objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                    receivingAmount += objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                }
                ARCustomerPaymentsInfo objCustomerPaymentsInfo = CreateCustomerPayments(objOpenDocumentsInfo, receivingAmount);
                if (objCustomerPaymentsInfo.ARCustomerPaymentID > 0)
                {
                    ARDocumentPaymentsInfo objDocumentPaymentsInfo = CreateDocumentPayments(objOpenDocumentsInfo, objCustomerPaymentsInfo, totalAmount);
                    if (objDocumentPaymentsInfo.ARDocumentPaymentID > 0)
                        CreateDocumentPaymentDetails(objOpenDocumentsInfo, objCustomerPaymentsInfo, objDocumentPaymentsInfo, lstPaymentDetails);
                }
            }
        }

        public static ARCustomerPaymentsInfo CreateCustomerPayments(AROpenDocumentsInfo objAROpenDocumentsInfo, double receivingAmount)
        {
            ARCustomerPaymentsController objCustomerPaymentsController = new ARCustomerPaymentsController();
            ARCustomerPaymentsInfo objCustomerPaymentsInfo = new ARCustomerPaymentsInfo();
            objCustomerPaymentsInfo.FK_ARCustomerID = objAROpenDocumentsInfo.FK_ARCustomerID;
            objCustomerPaymentsInfo.AACreatedUser = THSApp.CurrentUser;
            objCustomerPaymentsInfo.AACreatedDate = DateTime.Now;
            objCustomerPaymentsInfo.ARCustomerPaymentTotalAmount = receivingAmount;
            objCustomerPaymentsController.CreateObject(objCustomerPaymentsInfo);
            return objCustomerPaymentsInfo;
        }

        public static ARDocumentPaymentsInfo CreateDocumentPayments(AROpenDocumentsInfo objAROpenDocumentsInfo, ARCustomerPaymentsInfo objCustomerPaymentsInfo, double totalAmount)
        {
            ARDocumentPaymentsController objDocumentPaymentsController = new ARDocumentPaymentsController();
            ARDocumentPaymentsInfo objDocumentPaymentsInfo = new ARDocumentPaymentsInfo();

            objDocumentPaymentsInfo.AACreatedUser = THSApp.CurrentUser;
            objDocumentPaymentsInfo.AACreatedDate = DateTime.Now;
            objDocumentPaymentsInfo.FK_AROpenDocumentID = objAROpenDocumentsInfo.AROpenDocumentID;
            objDocumentPaymentsInfo.FK_ARCustomerPaymentID = objCustomerPaymentsInfo.ARCustomerPaymentID;

            objDocumentPaymentsInfo.ARDocumentPaymentAmount = objCustomerPaymentsInfo.ARCustomerPaymentTotalAmount;
            objDocumentPaymentsInfo.ARDocumentPaymentChangeAmount = objDocumentPaymentsInfo.ARDocumentPaymentAmount - totalAmount;
            objDocumentPaymentsController.CreateObject(objDocumentPaymentsInfo);
            return objDocumentPaymentsInfo;
        }

        public static void CreateDocumentPaymentDetails(AROpenDocumentsInfo objOpenDocumentsInfo, ARCustomerPaymentsInfo objCustomerPaymentsInfo, ARDocumentPaymentsInfo objDocumentPaymentsInfo, THSList<ARDocumentPaymentDetailsInfo> lstPaymentDetails)
        {
            ARDocumentPaymentDetailsController objDocumentPaymentDetailsController = new ARDocumentPaymentDetailsController();
            foreach (ARDocumentPaymentDetailsInfo objDocumentPaymentDetailsInfo in lstPaymentDetails)
                if (objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount != 0)
                {
                    switch (objDocumentPaymentDetailsInfo.ARPaymentMethodCombo)
                    {
                        case ADConfigValueUtility.cstPaymentMethodAccount:
                            {
                                ARCustomersController objCustomersController = new ARCustomersController();
                                ARCustomersInfo objCustomersInfo = (ARCustomersInfo)objCustomersController.GetObjectByID(objCustomerPaymentsInfo.FK_ARCustomerID);
                                if (objCustomersInfo != null)
                                {
                                    objCustomersInfo.AAUpdatedUser = THSApp.CurrentUser;
                                    objCustomersInfo.AAUpdatedDate = DateTime.Now;
                                    objCustomersInfo.ARCustomerOwing += objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                                    objCustomersController.UpdateObject(objCustomersInfo);
                                }
                            }
                            break;
                        case ADConfigValueUtility.cstPaymentMethodCreditNote:
                        case ADConfigValueUtility.cstPaymentMethodGiftVoucher:
                            {
                                switch (objOpenDocumentsInfo.AROpenDocumentType)
                                {
                                    case ADConfigValueUtility.cstOpenDocumentTypeSaleReceipt:
                                    case ADConfigValueUtility.cstOpenDocumentTypeLayBy:
                                        {
                                            ARCreditNotesController objCreditNotesController = new ARCreditNotesController();
                                            ARCreditNotesInfo objCreditNotesInfo = (ARCreditNotesInfo)objCreditNotesController.GetObjectByID(objDocumentPaymentDetailsInfo.FK_ARCreditNoteID);
                                            if (objCreditNotesInfo != null)
                                            {
                                                objCreditNotesInfo.AAUpdatedUser = THSApp.CurrentUser;
                                                objCreditNotesInfo.AAUpdatedDate = DateTime.Now;
                                                objCreditNotesInfo.ARCreditNoteRemainingAmount -= objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                                                objCreditNotesController.UpdateObject(objCreditNotesInfo);
                                            }
                                        }
                                        break;
                                    case ADConfigValueUtility.cstOpenDocumentTypeGoodsRefund:
                                        {
                                            ARCreditNotesController objCreditNotesController = new ARCreditNotesController();
                                            ARCreditNotesInfo objCreditNotesInfo = (ARCreditNotesInfo)objCreditNotesController.GetObjectByNo(objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailInfo);
                                            if (objCreditNotesInfo != null)
                                            {
                                                objCreditNotesInfo.AAUpdatedUser = THSApp.CurrentUser;
                                                objCreditNotesInfo.AAUpdatedDate = DateTime.Now;
                                                objCreditNotesInfo.ARCreditNoteTotalAmount -= objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                                                objCreditNotesInfo.ARCreditNoteRemainingAmount -= objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                                                objCreditNotesController.UpdateObject(objCreditNotesInfo);
                                            }
                                            else
                                            {
                                                objCreditNotesInfo = new ARCreditNotesInfo();
                                                objCreditNotesInfo.ARCreditNoteNo = THSApp.GetMainObjectNo("CreditNote");
                                                THSApp.UpdateObjectNumbering("CreditNote");
                                                objCreditNotesInfo.AACreatedUser = THSApp.CurrentUser;
                                                objCreditNotesInfo.AACreatedDate = DateTime.Now;
                                                objCreditNotesInfo.ARCreditNoteDate = DateTime.Now;
                                                
                                                //Get valid date from ADConfigValues
                                                ADConfigValuesController objConfigValuesController = new ADConfigValuesController();
                                                ADConfigValuesInfo objConfigValuesInfo = (ADConfigValuesInfo)objConfigValuesController.GetObjectByConfigKey(CreditNote.CreditNoteModule.cstCreditNoteConfigValidDays);
                                                objCreditNotesInfo.ARCreditNoteValidateDate = DateTime.Now.AddDays(Convert.ToInt32(objConfigValuesInfo.ADConfigKeyValue));

                                                objCreditNotesInfo.FK_ARCustomerID = objOpenDocumentsInfo.FK_ARCustomerID;
                                                objCreditNotesInfo.FK_HREmployeeID = objOpenDocumentsInfo.FK_HREmployeeID;
                                                objCreditNotesInfo.ARCreditNoteTypeCombo = objDocumentPaymentDetailsInfo.ARPaymentMethodCombo;
                                                objCreditNotesInfo.ARCreditNoteTotalAmount = -objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                                                objCreditNotesInfo.ARCreditNoteRemainingAmount = -objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount;
                                                objCreditNotesInfo.ARCreditNoteReference = objOpenDocumentsInfo.AROpenDocumentNo;
                                                objCreditNotesController.CreateObject(objCreditNotesInfo);
                                            }
                                        }
                                        break;
                                }
                            }
                            break;
                    }
                    objDocumentPaymentDetailsInfo.AACreatedUser = THSApp.CurrentUser;
                    objDocumentPaymentDetailsInfo.AACreatedDate = DateTime.Now;
                    objDocumentPaymentDetailsInfo.FK_ARDocumentPaymentID = objDocumentPaymentsInfo.ARDocumentPaymentID;
                    objDocumentPaymentDetailsController.CreateObject(objDocumentPaymentDetailsInfo);
                }
        }
        #endregion
    }
}
